#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>

typedef struct 
{
	ngx_str_t source;
	ngx_str_t target;
} ngx_http_auths;

typedef struct{
	ngx_array_t *configs;
} ngx_http_myconfig_t;



static ngx_int_t ngx_http_bingo_init(ngx_conf_t *cf);

static void *ngx_http_bingo_create_loc_conf(ngx_conf_t *cf);

static char *ngx_conf_set_bingo_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

/*
static char *ngx_http_hello_string(ngx_conf_t *cf,ngx_command_t *cmd,void *conf);

static char *ngx_http_hello_counter(ngx_conf_t *cf,ngx_command_t *cmd, void *conf);
*/


static ngx_command_t ngx_http_hello_commands[] = {
	{ngx_string("bingoConf"),
	NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
	ngx_conf_set_bingo_slot,
	NGX_HTTP_LOC_CONF_OFFSET,
	offsetof(ngx_http_myconfig_t,configs),
    NULL},
     
    ngx_null_command
};


 
static ngx_http_module_t ngx_http_hello_module_ctx = {
	NULL, /*preconfiguration */
	ngx_http_bingo_init, /*postconfiguration */
	NULL,  /* create main configuration */
	NULL, /*init main configuration */

	NULL,   /*create server configuration */
	NULL,   /*merge server configuration */

	ngx_http_bingo_create_loc_conf,  /*create location configuration */
	NULL    /* merge location configuration */
};

ngx_module_t ngx_http_myconfig_module = {
	NGX_MODULE_V1,
	&ngx_http_hello_module_ctx,    /*module context */
	ngx_http_hello_commands,       /* module directives */
	NGX_HTTP_MODULE,               /* module type */
	NULL,                          /* init master */
	NULL,							/*init module */
	NULL,							/*int process */
	NULL,							/*init thread */
	NULL,							/* exit thread */
	NULL,							/* exit process */
	NULL,							/* exit master */
	NGX_MODULE_V1_PADDING
};



static ngx_int_t ngx_http_hello_handler(ngx_http_request_t *r){
	ngx_int_t rc;
	ngx_buf_t *b;
	ngx_chain_t out;
 	u_char ngx_hello_string[1024] = {0};
	ngx_uint_t content_length  = 0;

	ngx_log_error(NGX_LOG_EMERG, r->connection->log,0,"ngx_http_hello_handler is called!");

 	 
 ngx_sprintf(ngx_hello_string,"%s","hello world");
 
	content_length = ngx_strlen(ngx_hello_string);

	/* we response to 'GET' and 'HEAD' requests only */
	if (!(r->method &(NGX_HTTP_GET|NGX_HTTP_HEAD)))
	{
		return NGX_HTTP_NOT_ALLOWED;
	}

	/* discard request body, since we don't need it here */
	rc = ngx_http_discard_request_body(r);

	if (rc!=NGX_OK)
	{
		return rc;
	}

	/** set the 'Content-type' header */
	/**
	* r->headers_out.content_type.len = sizeof("text/")
    * r->headers_out.content_type.data = (u_char *)"text/html";
	*/

	ngx_str_set(&r->headers_out.content_type,"text/html");
	if(r->method == NGX_HTTP_HEAD){
		r->headers_out.status = NGX_HTTP_OK;
		r->headers_out.content_length_n = content_length;

		return ngx_http_send_header(r);
	}

	b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));

	if(b == NULL){
		return NGX_HTTP_INTERNAL_SERVER_ERROR;
	}

	/* attch this buffer to the buffer chain */
	out.buf = b;
	out.next = NULL;

	/* adjust the pointers of the buffer */
	b->pos = ngx_hello_string;
	b->last = ngx_hello_string + content_length;
	b->memory = 1; /*this buffer is in memory */
	b->last_buf = 1; /* this is the last buffer in the buffer chain */

	/*set the status line */
	r->headers_out.status = NGX_HTTP_OK;
	r->headers_out.content_length_n = content_length;

	/* send the headers of your response */
	rc = ngx_http_send_header(r);

	if (rc == NGX_ERROR || rc>NGX_OK || r->header_only)
	{
		return rc;
	}

	/*send the buffer chain of your response */

	return ngx_http_output_filter(r,&out);
}


static void *ngx_http_bingo_create_loc_conf(ngx_conf_t *cf){
	ngx_http_myconfig_t* local_conf = NULL;
	local_conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_myconfig_t));
	if (local_conf == NULL)
	{
		return NULL;
	}

	 		ngx_log_error(NGX_LOG_EMERG,cf->log,0,"ngx_http_bingo_create_loc_conf ---------------------");

    local_conf->configs = NULL;

    return local_conf;
}
 
static char *ngx_conf_set_bingo_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf){
	 char  *p = conf;

    ngx_str_t         *value;
    ngx_array_t      **a;
    ngx_http_auths      *auth;
 
     	    ngx_log_error(NGX_LOG_EMERG, cf->log,0,"start bingo slot.....");

    a = (ngx_array_t **) (p + cmd->offset);
     	    ngx_log_error(NGX_LOG_EMERG, cf->log,0,"111111111.....");

    if (*a == NULL) {
    	    ngx_log_error(NGX_LOG_EMERG, cf->log,0,"create array.....");

        *a = ngx_array_create(cf->pool, 3, sizeof(ngx_http_auths));
        if (*a == NULL) {
            return NGX_CONF_ERROR;
        }
    }
ngx_log_error(NGX_LOG_EMERG, cf->log,0,"222222.....");

    auth = ngx_array_push(*a);
    if (auth == NULL) {
        return NGX_CONF_ERROR;
    }
ngx_log_error(NGX_LOG_EMERG, cf->log,0,"333333.....");

    value = cf->args->elts;

    auth->source = value[1];
    auth->target = value[2];
    ngx_log_error(NGX_LOG_EMERG, cf->log,0,"444444.....%s",value[2].data);

    //ngx_log_error(NGX_LOG_EMERG, cf->log,0,"auth %V, %V",auth->source,auth->target);
    

    return NGX_CONF_OK;
}

static ngx_int_t ngx_http_bingo_init(ngx_conf_t *cf){
	ngx_http_handler_pt *h;
	ngx_http_core_main_conf_t *cmcf;


   ngx_log_error(NGX_LOG_EMERG, cf->log,0,"post configuration.....");
	cmcf = ngx_http_conf_get_module_main_conf(cf,ngx_http_core_module);
    
 
     ngx_http_conf_ctx_t* http_root_conf = (ngx_http_conf_ctx_t*)ngx_get_conf(cf->cycle->conf_ctx, ngx_http_module);

    ngx_http_myconfig_t  *mycf;
    mycf = (ngx_http_myconfig_t  *)http_root_conf->loc_conf[ngx_http_myconfig_module.ctx_index];
     
    
   ngx_log_error(NGX_LOG_EMERG, cf->log,0,"post configuration...22222..%u",&mycf->configs->nelts);

    
   	   
	h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers);
	if(h == NULL ){
		return NGX_ERROR;
	}

	*h = ngx_http_hello_handler;
	return NGX_OK;
}